#include "SessionUtil.h"
using namespace std;



namespace DUOMISESSIONUTIL{

	void _set_rc4_key(RC4_KEY *key) {
		char p[] = "mcloud";
		RC4_set_key(key, strlen(p), (unsigned char *)p);
	}


	int32_t _decodeBase64(const unsigned char *src, int32_t src_len,
			unsigned char *out, int32_t *out_len) {
		int32_t i = 0, j = 0 ;
		unsigned char encodeBase64map[] =
			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
		unsigned char decodeBase64map[256] = {0} ;

		for (j = src_len; j>0 && '='==src[j-1]; --j) ;
		i = (j/4)*3+(j%4+1)/2;

		if (out != NULL) {
			if (*out_len < i)
				return -1;
			*out_len = i;
		} else {
			*out_len = i ;
			return 0 ;
		}

		j = sizeof(encodeBase64map);
		for (i=0; i<j; ++i)
			decodeBase64map[ encodeBase64map[i] ] = i;
		for (i=j=0; i<src_len; i+=4) {
			out[j++] = decodeBase64map[src[i  ]] << 2 | decodeBase64map[src[i+1]] >> 4;
			out[j++] = decodeBase64map[src[i+1]] << 4 | decodeBase64map[src[i+2]] >> 2;
			out[j++] = decodeBase64map[src[i+2]] << 6 | decodeBase64map[src[i+3]];
		}
		return *out_len;
	}


	int32_t _decodeBase62(const std::string &input,
			std::string &output){


		string tmp;
		uint32_t i = 0;
		for (; i<input.size(); i++) {
			if (input[i] == 'i') {
				if (input[i+1] == '0') {
					tmp.append("i");
				} else if (input[i+1] == '1') {
					tmp.append("+");
				} else if (input[i+1] == '2') {
					tmp.append("/");
				} else if (input[i+1] == '3') {
					tmp.append("=");
				} else {
					return -1;
				}
				i++;
			} else {
				tmp.append(1, input[i]);
			}
		}
		unsigned char *buf = (unsigned char *)malloc((tmp.size()/4 + 1) * 3);
		if (!buf) {
			return -1;
		}
		memset(buf, 0, (tmp.size()/4+1)*3);
		int32_t size = (tmp.size()/4+1)*3;
		//int ret = _decodeBase64((unsigned char *)tmp.c_str(), tmp.size(),
		//		buf, &size);
		_decodeBase64((unsigned char *)tmp.c_str(), tmp.size(), buf, &size);
		output.append((char *)buf, size);
		free(buf);
		return 0;

	}



}



int32_t getDuomiUidFromSession(const char *sid,const int32_t len) {
	if (!sid || !len) {
		cerr<<"session empty"<<endl;
		return -1;
	}

	string session(sid,len);
	string uid;

	string tmp;
	if(DUOMISESSIONUTIL::_decodeBase62(session, tmp)<0){
		cerr <<"_decodeBase62 error"<<endl;
		return -1;	
	}
	RC4_KEY key;
	DUOMISESSIONUTIL::_set_rc4_key(&key);
	char *out = (char *)malloc(session.size());
	memset(out, 0 ,session.size());
	RC4(&key, tmp.size(), (unsigned char *)tmp.c_str(), (unsigned char *)out);
	char *p = strchr(out, '#');
	if (p == NULL) {
		cerr << "p is NULL" << endl;
		return -1;
	}
	*p = '\0';
	uid = out;
	free(out);

	for(uint32_t i = 0;i<uid.size();i++){
		if(!(uid.at(i) >= '0' && uid.at(i) <= '9')){
			uid.clear();	
			cerr << "get uid invalid!!!" << endl;
			return -1;
		}
	}
	
	int32_t i_uid = 0;
	sscanf(uid.c_str(),"%u",&i_uid);
	return i_uid;
}



/*
int32_t getDuomiUidFromSession(const string &session,
		string &uid){

	//if(!uid){
	//	return -1;
	//}

	if (session == "") {
		return -1;
	}

	string tmp;

	if(DUOMISESSIONUTIL::_decodeBase62(session, tmp)<0){
		return -1;	
	}
	RC4_KEY key;
	DUOMISESSIONUTIL::_set_rc4_key(&key);
	char *out = (char *)malloc(session.size());
	memset(out, 0 ,session.size());
	RC4(&key, tmp.size(), (unsigned char *)tmp.c_str(), (unsigned char *)out);
	char *p = strchr(out, '#');
	if (p == NULL) {
		return -1;
	}
	*p = '\0';
	uid = out;
	free(out);

	for(uint32_t i = 0;i<uid.size();i++){
		if(!(uid.at(i) >= '0' && uid.at(i) <= '9')){
			uid.clear();	
			return -1;
		}
	}

	return 0;
}
*/



